package com.itheima.stock.service.impl;

import com.google.common.collect.Lists;
import com.itheima.stock.config.TaskExecutePool;
import com.itheima.stock.constant.ParseType;
import com.itheima.stock.face.StockCacheFace;
import com.itheima.stock.mapper.*;
import com.itheima.stock.pojo.entity.StockBlockRtInfo;
import com.itheima.stock.pojo.entity.StockMarketIndexInfo;
import com.itheima.stock.pojo.entity.StockOuterMarketIndexInfo;
import com.itheima.stock.pojo.entity.StockRtInfo;
import com.itheima.stock.pojo.vo.StockInfoConfig;
import com.itheima.stock.service.StockTimerTaskService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.utils.ParserStockInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.SimpleFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private StockInfoConfig stockInfoConfig;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Autowired
    private ParserStockInfoUtil parserStockInfoUtil;
    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;
    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private StockOuterMarketIndexInfoMapper stockOuterMarketIndexInfoMapper;
    @Autowired
    private StockCacheFace stockCacheFace;

    @Override
    public void getInnerMarketInfo() {

        String url = stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getInner());

        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        HttpEntity<Object> entity = new HttpEntity<>(headers);

        ResponseEntity<String> exchange = restTemplate.exchange(url,HttpMethod.POST, entity, String.class);
        String body = exchange.getBody();

        String reg = "var hq_str_(.*)=\"(.*)\";";

        Pattern compile = Pattern.compile(reg);

        ArrayList<StockMarketIndexInfo> rtInfos = new ArrayList<>();

        Matcher matcher = compile.matcher(body);
        while(matcher.find()){
            String marketCode = matcher.group(1);
            String otherInfos = matcher.group(2);
            String[] infos = otherInfos.split(",");
//            rtInfo.setId();

            //0：指数名称
            String marketName = infos[0];
            //1：开盘点
            BigDecimal openPoint = new BigDecimal(infos[1]);
            //2：前收盘点
            BigDecimal preClosePoint = new BigDecimal(infos[2]);
            //3：当前点
            BigDecimal curPoint = new BigDecimal(infos[3]);
            //4：最高点
            BigDecimal maxPoint = new BigDecimal(infos[4]);
            //5：最低点
            BigDecimal minPoint = new BigDecimal(infos[5]);
            //8：成交量
            Long tradeAmount = Long.valueOf(infos[8]);
            //9：成交金额
            BigDecimal tradeVolume = new BigDecimal(infos[9]);
            //30：当前日期
            //31：当前时间
            Date curTime = DateTimeUtil.getDateTimeWithoutSecond(infos[30] + " " + infos[31]).toDate();

            //主键字段
            long id = idWorker.nextId();

            StockMarketIndexInfo rtInfo = StockMarketIndexInfo.builder()
                    .id(id)
                    .marketCode(marketCode)
                    .marketName(marketName)
                    .preClosePoint(preClosePoint)
                    .openPoint(openPoint)
                    .curPoint(curPoint)
                    .minPoint(minPoint)
                    .maxPoint(maxPoint)
                    .tradeAmount(tradeAmount)
                    .tradeVolume(tradeVolume)
                    .curTime(curTime).build();
            rtInfos.add(rtInfo);
        }
        System.out.println(rtInfos);
        log.info("采集的当前大盘数据：{}",rtInfos);
        //批量插入
        if (CollectionUtils.isEmpty(rtInfos)) {
            return;
        }
        int count = stockMarketIndexInfoMapper.insertBatch(rtInfos);
        log.info("批量插入了：{}条数据",count);
        rabbitTemplate.convertAndSend("stockExchange","inner.market",new Date());
    }

    @Override
    public void getStockRtIndex() {
        List<String> stockCodes = stockCacheFace.getAllStockCodeWithPredix();
        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
        Lists.partition(stockCodes, 20).forEach(stockCode ->{
            threadPoolTaskExecutor.execute(()->{
                String url = stockInfoConfig.getMarketUrl() + String.join(",", stockCode);
                ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
                String body = exchange.getBody();
                List infos = parserStockInfoUtil.parser4StockOrMarketInfo(body, ParseType.ASHARE);
                log.info("数据量：{}",infos.size());
                stockRtInfoMapper.insertBatch(infos);
            });
            rabbitTemplate.convertAndSend("stockExchange","stock.info",new Date());
        });
    }

    @Override
    public void getBlockRtInfo() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
        String url = stockInfoConfig.getBlockUrl();
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        String body = exchange.getBody();
        List<StockBlockRtInfo> infos = parserStockInfoUtil.parse4StockBlock(body);
        log.info("板块数量:{}",infos.size());
            threadPoolTaskExecutor.execute(()->{
                stockBlockRtInfoMapper.insertBatch(infos);
                System.out.println("插入成功");
            });
            rabbitTemplate.convertAndSend("stockExchange","block.info",new Date());
    }

    @Override
    public void getOuterMarketInfo() {
        String url = "http://hq.sinajs.cn/list=" + String.join(",", stockInfoConfig.getOuter());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer", "https://finance.sina.com.cn/stock/");
        headers.add("User-Agent", ":Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0");
        HttpEntity<String> entity = new HttpEntity<>(headers);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        String body = exchange.getBody();
        List infos = parserStockInfoUtil.parser4StockOrMarketInfo(body, ParseType.OUTER);
        log.info("外盘数量:{}", infos.size());
        threadPoolTaskExecutor.execute(() -> {
            stockOuterMarketIndexInfoMapper.insertBatch(infos);
            System.out.println("插入成功");
        });
        rabbitTemplate.convertAndSend("stockExchange", "outer.market", new Date());
    }
}



//https://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php